package com.profound.notes.component;

import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Objects;

import static com.profound.notes.component.Recycler.DIRECTION_DOWN;
import static com.profound.notes.component.Recycler.DIRECTION_UP;

/**
 * @author zjwujlei
 * @date 2021/5/2
 * @email zjwujlei@sina.com
 * @description
 */

public class WaterfallLayoutManager extends SpanLayoutManager {

    public WaterfallLayoutManager(int spanNum) {
        super(spanNum);
    }


    public void setOrientation(int orientation) {
        super.setOrientation(orientation);
        //当前只实现了从上盗下垂直布局
        int left = 0;
        int spanWidth = mWidthSize/mSpanNum;
        for(Span span:mSpans){
            span.left = left;
            left +=spanWidth;
        }
    }

    public void setRecycler(Recycler recycler){
        mRecycler = recycler;
    }

    public void setProvider(BaseItemProvider provider){
        mProvider = provider;
    }

    /**
     *
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @param direction
     * @return
     */
    public synchronized boolean fill(float left,float top,float right,float bottom,int direction){

        int spanWidth = mWidthSize/mSpanNum;
        if(mSpans == null){
            mSpans = new Span[mSpanNum];
            for(int i=0;i<mSpanNum;i++){
                Span span = new Span();
                span.index = i;
                mSpans[i] = span;
                span.left = (int) (left + i*spanWidth);
            }
        }

        LinkedList<RecyclerItem> attached = mRecycler.getAttachedScrap();
        if(attached.isEmpty()){
            mRecycler.getAllScrap().clear();
            int count = mProvider.getCount();
            int okSpan = 0;
            for (int i=0;i<count;i++){
                Span span = getMinSpanWithEndLine();
                RecyclerItem item = fillChild(span.left,span.endLine,i);
                item.span = span;
                if(item.positionY>=top && item.positionY<=bottom+item.height){//在显示区域
                    mRecycler.addItem(i,item);
                    mRecycler.attachItemToEnd(item);
                }else{
                    mRecycler.recycle(item);
                }


                span.endLine += item.height+item.marginTop+item.marginBottom;
                if(span.endLine>bottom){
                    okSpan++;
                }
                if(okSpan>=mSpanNum){
                    break;
                }
            }
            return true;
        }else{
            if(direction == DIRECTION_UP){
                RecyclerItem last = attached.peekLast();
                int count = mProvider.getCount();
                if(last.index == count-1 && last.getBottom()<=bottom){//已经到底
                    return false;
                }else{
                    //先回收
                    RecyclerItem first = attached.peekFirst();
                    while(first != null && first.getBottom()<top){
                        mRecycler.recycle(first);//recycle本身会remove
                        first.span.startLine += first.getVSpace();
                        first = attached.peekFirst();
                    }

                    Span minEndLineSpan = getMinSpanWithEndLine();
                    int index = last.index+1;
                    while(index<count && minEndLineSpan.endLine<=bottom){//需要填充
                        RecyclerItem item;
                        if(mRecycler.getAllScrap().size()>index){
                            item = mRecycler.getAllScrap().get(index);
                            mRecycler.recoverToEnd(item);
                        }else{
                            item = fillChild(minEndLineSpan.left,minEndLineSpan.endLine,index);
                            item.span = minEndLineSpan;
                            mRecycler.attachItemToEnd(item);
                            mRecycler.addItem(index,item);
                        }
                        item.span.endLine += item.getVSpace();
                        minEndLineSpan = getMinSpanWithEndLine();
                        index++;
                    }
                    return true;
                }
            }else if(direction == DIRECTION_DOWN){
                RecyclerItem first = attached.peekFirst();
                int count = mProvider.getCount();
                if(first.index == 0 && first.getTop()>=top){//已经到顶
                    return false;
                }else{
                    //先回收
                    RecyclerItem last = attached.peekLast();
                    while(last != null && last.getTop()>bottom){
                        mRecycler.recycle(last);//recycle本身会remove
                        last.span.endLine -= last.getVSpace();
                        last = attached.peekFirst();
                    }

                    Span maxStartLineSpan = getMaxSpanWithStartLine();
                    int index = first.index-1;
                    while(index>=0 && maxStartLineSpan.startLine>=top){//需要填充
                        RecyclerItem item = mRecycler.getAllScrap().get(index);
                        if(item != null){
                            mRecycler.recoverToStart(item);
                            item.span.startLine -= item.getVSpace();
                        }else{
                            //理论上不存在
                        }
                        maxStartLineSpan = getMaxSpanWithStartLine();
                        index--;
                    }

                    return true;
                }
            }
        }

        return true;

    }



    /**
     * 获取
     */
    private Span getMinSpanWithEndLine(){
        Span result = mSpans[0];
        for(Span span:mSpans){
            if(result == span){
                continue;
            }
            if(result.endLine>span.endLine){
                result = span;
            }
        }
        return result;
    }

    private Span getMaxSpanWithStartLine(){
        Span result = mSpans[0];
        for(Span span:mSpans){
            if(result == span){
                continue;
            }
            if(result.startLine<span.startLine){
                result = span;
            }
        }
        return result;
    }

    private RecyclerItem fillChild(int left,int top,int index){

        int childWidth = mWidthSize / mSpanNum;
        Component child = mRecycler.getView(index,mSpanLayout);
        ComponentContainer.LayoutConfig lc = child.getLayoutConfig();
        int childWidthMeasureSpec = Component.EstimateSpec.getChildSizeWithMode(
                childWidth - lc.getMarginLeft() - lc.getMarginRight(), mWidthMode, Component.EstimateSpec.PRECISE);
        int childHeightMeasureSpec = Component.EstimateSpec.getChildSizeWithMode(
                lc.height, mHeightMode, Component.EstimateSpec.UNCONSTRAINT);
        child.estimateSize(childWidthMeasureSpec, childHeightMeasureSpec);
        RecyclerItem item = new RecyclerItem();
        item.index = index;
        item.width = childWidth - lc.getMarginLeft() - lc.getMarginRight();
        item.height = child.getEstimatedHeight();
        item.marginLeft = lc.getMarginLeft();
        item.marginTop = lc.getMarginTop();
        item.marginRight = lc.getMarginRight();
        item.marginBottom = lc.getMarginBottom();
        item.positionX = left;
        item.positionY = top;
        item.child = child;

        mSpanLayout.addComponent(child);

        return item;

    }



}
